package socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

/**
 * 聊天室的客户端
 * @author Xiloer
 *
 */
public class Client {
	/*
	 * java.net.Socket 套接字
	 * Socket封装了TCP协议的通讯细节，使用它就可以与服务端建立网络连接了，
	 * 并且进行通讯。这里的通讯是以两条流的读写完成与服务端的数据交换的。
	 */
	private Socket socket;
	/**
	 * 客户端构造方法，用于初始化客户端
	 */
	public Client() {
		try {
			/*
			 * 实例化Socket时需要传入两个参数:
			 * 1:服务端的地址信息(IP)
			 * 2:服务端打开的端口
			 * 
			 * 我们可以通过IP找到网络上的服务端计算机，通过其打开的端口
			 * 可以连接到服务端应用程序。
			 */
			System.out.println("正在连接服务端...");
			socket = new Socket("localhost",8088);
			System.out.println("已连接服务端!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 客户端开始工作的方法
	 */
	public void start() {
		try {
			//先启动用于读取服务端发送过来消息的线程
			ServerHandler handler = new ServerHandler();
			Thread t = new Thread(handler);
			t.start();
			/*
			 * Socket提供的方法:
			 * OutputStream getOutputStream()
			 * 通过socket的该方法获取的输出流写出的字节会通过网络发送给
			 * 远端计算机。
			 */
			OutputStream out = socket.getOutputStream();
			
			OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
			BufferedWriter bw = new BufferedWriter(osw);
			PrintWriter pw = new PrintWriter(bw,true);
			
			Scanner scanner = new Scanner(System.in);
			while(true) {
				String message = scanner.nextLine();
				pw.println(message);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		Client client = new Client();
		client.start();
	}
	/**
	 * 该线程负责循环读取服务端发送过来的消息
	 * @author 范传奇
	 *
	 */
	private class ServerHandler implements Runnable{
		public void run() {
			try {
				InputStream in = socket.getInputStream();
				InputStreamReader isr = new InputStreamReader(in,"UTF-8");
				BufferedReader br = new BufferedReader(isr);
				
				String message;
				while((message = br.readLine())!=null) {
					System.out.println(message);
				}
				
			} catch (Exception e) {
				
			}
		}
	}
}









